home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Sherlock 2.0 / Sherlock_DevLib / sl_util.c < prev    next >
Text File  |  1996-03-12  |  4KB  |  262 lines

  1. /*
  2.     Sherlock utility routines.
  3.  
  4.     source:  sl_util.c
  5.     started: November 4, 1993.
  6.     version: March 12, 1996.
  7. */
  8.  
  9. #include <LIBlib.h>
  10. #include <LIBend.h>
  11.  
  12. #include <sl.h>
  13. #include <sl2.h>
  14.  
  15. #include <ctype.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #ifdef applec
  20.     #include <SegLoad.h>
  21.     #include <OSUtils.h>
  22. #endif
  23.  
  24. /*
  25.     Abort Sherlock.
  26.  
  27.     This is to be called if an error prevents Sherlock from being initialized.
  28.     Assume nothing is available that must be initialized.
  29. */
  30. void
  31. sl_abort(int beeps)
  32. {
  33.  
  34. #if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
  35.     int i;
  36.     for (i = 0; i < beeps; i++) {
  37.         SysBeep(20);
  38.     }
  39. #endif
  40.  
  41.     end_abort();
  42. }
  43.  
  44. /*
  45.     Function prototypes of internal routines.
  46. */
  47. static int    sl_hash    (char *);
  48.  
  49. /*
  50.     Return the name on the call stack n levels back.
  51. */
  52. char *
  53. sl_callname(int n)
  54. {
  55.     register sl_snode * sp;
  56.  
  57.     if (n < 0 || (sl_level - n - 1 < 0) || sl_stack == NULL) {
  58.         return "";
  59.     }
  60.     else {
  61.         char * the_name;
  62.         sp = &sl_stack [sl_level - n - 1];
  63.         the_name = sp -> node -> name;
  64.         return (the_name[0] == '!' || the_name[0] == '+') ? the_name+1 : the_name;
  65.     }
  66. }
  67.  
  68. /*
  69.     SL_CLEAR macro--Clear all statistics.
  70. */
  71. void
  72. sl_clear(void)
  73. {
  74.     register int i;
  75.     register sl_node * p;
  76.  
  77.     /* 5/19/92 */
  78.     if (sl_htab == NULL) {
  79.         return;
  80.     }
  81.     for (i = 0; i < SL_MAX_HASH; i++) {
  82.         for (p = sl_htab[i]; p; p = p -> next) {
  83.             p -> time =  0;
  84.             p -> time2 = 0;
  85.             p -> calls  =  0;
  86.         }
  87.     }
  88. }
  89.  
  90. /*
  91.     Check the string arguments to a tracing function.
  92.  
  93.     The sl_cname global variable points to a string containing the
  94.     name of the macro responsible for invoking the check.
  95. */
  96. void
  97. sl_check(register char *s)
  98. {
  99.     register char c;
  100.     register int i;
  101.     char *old_s;
  102.  
  103.     old_s = s;
  104.  
  105.     /* Check for null string. */
  106.     if (!*s) {
  107.         es("sl_check: "); es(sl_cname);
  108.         es(": null string @ "); eptr(s); enl();
  109.         sl_exit();
  110.     }
  111.  
  112.     /* Skip over ! and - characters. */
  113.     if (*s == '!' || *s == '-') {
  114.         s++;
  115.     }
  116.     if (*s == '!' || *s == '-') {
  117.         s++;
  118.     }
  119.  
  120.      /* 6/27/89: allow up to 31 character names. */
  121.     for (i = 0; i < 31; i++) {
  122.         c = *s++;
  123.         if (c == '\0') {
  124.             return ;
  125.         }
  126.  
  127.         /* Allow only identifiers and wild cards. */
  128.         if (!isalnum(c) && c != '_' && c != '*' && c != '?') {
  129.             es("sl_check: "); es(sl_cname);
  130.             es(": bad character: "); echar(c);
  131.             es(" in "); es(old_s);
  132.             es(" @ "); eptr(s); enl();
  133.             sl_exit();
  134.         }
  135.     }
  136.  
  137.     es("sl_check: "); es(sl_cname);
  138.     es(": run on argument: "); es(old_s);
  139.     es(" @ "); eptr(s); enl();
  140.     sl_exit();
  141. }
  142.  
  143. /*
  144.     Print out n periods.
  145. */
  146. void
  147. sl_dots(n)
  148. int n;
  149. {
  150.     int i;
  151.  
  152.     ecnl();
  153.     if (!sl_nodots) {
  154.         for(i = 0; i < n+1; i++) {
  155.             echar('.');
  156.         }
  157.     }
  158. }
  159.  
  160. /*
  161.     Do whatever is necessary to terminate Sherlock.
  162. */
  163. void
  164. sl_exit(void)
  165. {
  166.  
  167. #if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
  168.     SysBeep( 5L );
  169.     es("Press the mouse to continue...\n");
  170.     while(!Button()) {
  171.         ;
  172.     }
  173.     ExitToShell();
  174. #else
  175.     exit(1);
  176. #endif
  177.  
  178. }
  179.  
  180. /*
  181.     Return a pointer to the node for s.
  182.     Set the global sl_cname to macro_type.
  183.     This is for internal use only.
  184.     Users should use sl_findname in macro.c.
  185. */
  186.  
  187. sl_node *
  188. sl_find(char *macro_type, char *s)
  189. {
  190.     register int i;
  191.     register sl_node *p, *q, *node;
  192.     register int hash;
  193.  
  194.     /* 5/19/92 */
  195.     if (sl_htab == NULL) {
  196.         sl_abort(SL_ABORT_FIND);
  197.     }
  198.  
  199.     /* Update global error string. */
  200.     if (macro_type != NULL) {
  201.         sl_cname = macro_type;
  202.     }
  203.  
  204.     /* Skip over ! and - characters. */
  205.     if (*s == '!' || *s == '-') {
  206.         s++;
  207.     }
  208.     if (*s == '!' || *s == '-') {
  209.         s++;
  210.     }
  211.  
  212.     /* Search the proper index table. */
  213.     hash = sl_hash(s);
  214.     p = sl_htab [hash];
  215.     if (p != NULL) {
  216.         i = strcmp(s, p -> name);
  217.         if (i == 0) {
  218.             return p;
  219.         }
  220.     }
  221.     if (p == NULL || i < 0) {
  222.         sl_check(s);
  223.         node = sl_new(s);
  224.         sl_htab [hash] = node;
  225.         node -> next  = p;
  226.         return node;
  227.     }
  228.  
  229.     /* Search the list for the node. */
  230.     for (q = p, p = p -> next; p; q = p, p = p -> next) {
  231.         i = strcmp(s, p -> name);
  232.         if (i == 0) {
  233.             return p;
  234.         }
  235.         else if (i < 0) {
  236.             break;
  237.         }
  238.     }
  239.  
  240.     /* Not found. */
  241.     sl_check(s);
  242.     node = sl_new(s);
  243.     q -> next    = node;
  244.     node -> next = p;
  245.     return node;
  246. }
  247.  
  248. /*
  249.     Compute hash code for the string s.
  250. */
  251. static int
  252. sl_hash(register char *s)
  253. {
  254.     register unsigned int hash = 0;
  255.  
  256.     while (*s) {
  257.         hash += hash + hash + (unsigned int) *s++;
  258.         hash %= SL_MAX_HASH;
  259.     }
  260.     return (int) hash;
  261. }
  262.